<template>
  <transition-group
    name="toast"
    tag="div"
    class="fixed top-6 right-6 z-[9999] space-y-3 pointer-events-none"
  >
    <div
      v-for="toast in toasts"
      :key="toast.id"
      :class="[
        'toast-item',
        `toast-${toast.type}`,
        'pointer-events-auto'
      ]"
    >
      <div class="flex items-center gap-3">
        <!-- 图标 -->
        <div class="flex-shrink-0">
          <svg v-if="toast.type === 'success'" class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
            <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd" />
          </svg>
          <svg v-else-if="toast.type === 'error'" class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
            <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd" />
          </svg>
          <svg v-else-if="toast.type === 'warning'" class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
            <path fill-rule="evenodd" d="M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z" clip-rule="evenodd" />
          </svg>
          <svg v-else class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
            <path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-7-4a1 1 0 11-2 0 1 1 0 012 0zM9 9a1 1 0 000 2v3a1 1 0 001 1h1a1 1 0 100-2v-3a1 1 0 00-1-1H9z" clip-rule="evenodd" />
          </svg>
        </div>

        <!-- 内容 -->
        <div class="flex-1">
          <p v-if="toast.title" class="font-semibold">{{ toast.title }}</p>
          <p class="text-sm">{{ toast.message }}</p>
        </div>

        <!-- 关闭按钮 -->
        <button
          @click="removeToast(toast.id)"
          class="flex-shrink-0 text-gray-400 hover:text-white transition-colors"
        >
          <svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
            <path fill-rule="evenodd" d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" clip-rule="evenodd" />
          </svg>
        </button>
      </div>

      <!-- 进度条 -->
      <div v-if="toast.duration" class="absolute bottom-0 left-0 right-0 h-1 bg-white/10">
        <div
          class="h-full transition-all"
          :class="`bg-${getColorClass(toast.type)}`"
          :style="{ width: `${toast.progress}%` }"
        />
      </div>
    </div>
  </transition-group>
</template>

<script setup lang="ts">
import { ref, onMounted } from 'vue'

interface Toast {
  id: number
  type: 'success' | 'error' | 'warning' | 'info'
  title?: string
  message: string
  duration?: number
  progress: number
}

const toasts = ref<Toast[]>([])
let nextId = 0

const getColorClass = (type: string) => {
  const colors: Record<string, string> = {
    success: '[#42d392]',
    error: '[#ff6b6b]',
    warning: '[#ffa500]',
    info: '[#647eff]'
  }
  return colors[type] || colors.info
}

const addToast = (options: Omit<Toast, 'id' | 'progress'>) => {
  const id = nextId++
  const toast: Toast = {
    id,
    type: options.type,
    title: options.title,
    message: options.message,
    duration: options.duration || 3000,
    progress: 100
  }

  toasts.value.push(toast)

  // 自动移除
  if (toast.duration) {
    const startTime = Date.now()
    const interval = setInterval(() => {
      const elapsed = Date.now() - startTime
      const progress = Math.max(0, 100 - (elapsed / toast.duration!) * 100)
      
      const toastIndex = toasts.value.findIndex(t => t.id === id)
      if (toastIndex !== -1) {
        toasts.value[toastIndex].progress = progress
      }

      if (elapsed >= toast.duration!) {
        clearInterval(interval)
        removeToast(id)
      }
    }, 10)
  }

  return id
}

const removeToast = (id: number) => {
  const index = toasts.value.findIndex(t => t.id === id)
  if (index !== -1) {
    toasts.value.splice(index, 1)
  }
}

const success = (message: string, title?: string, duration?: number) => {
  return addToast({ type: 'success', message, title, duration })
}

const error = (message: string, title?: string, duration?: number) => {
  return addToast({ type: 'error', message, title, duration })
}

const warning = (message: string, title?: string, duration?: number) => {
  return addToast({ type: 'warning', message, title, duration })
}

const info = (message: string, title?: string, duration?: number) => {
  return addToast({ type: 'info', message, title, duration })
}

// 暴露方法供外部使用
defineExpose({
  addToast,
  removeToast,
  success,
  error,
  warning,
  info
})
</script>

<style scoped>
.toast-item {
  @apply backdrop-blur-xl rounded-lg p-4 shadow-2xl border relative overflow-hidden;
  min-width: 300px;
  max-width: 400px;
  animation: slideIn 0.3s ease-out;
}

.toast-success {
  @apply bg-[#0a2a1a]/80 border-[#42d392]/30 text-[#42d392];
}

.toast-error {
  @apply bg-[#2a0a0a]/80 border-[#ff6b6b]/30 text-[#ff6b6b];
}

.toast-warning {
  @apply bg-[#2a1a0a]/80 border-[#ffa500]/30 text-[#ffa500];
}

.toast-info {
  @apply bg-[#0a1a2a]/80 border-[#647eff]/30 text-[#647eff];
}

.toast-enter-active,
.toast-leave-active {
  transition: all 0.3s ease;
}

.toast-enter-from {
  transform: translateX(400px);
  opacity: 0;
}

.toast-leave-to {
  transform: translateX(400px);
  opacity: 0;
}

@keyframes slideIn {
  from {
    transform: translateX(400px);
    opacity: 0;
  }
  to {
    transform: translateX(0);
    opacity: 1;
  }
}
</style>
